//
//  ARTWathDataAnalysis.m
//  ChartsDemo
//
//  Created by yunda on 2021/10/25.
//

#import "ARTWathDataAnalysis.h"

#define kLogReceive @"***-***-***R接收-"
#define kLogSend @"***-***-***S发送-"
#define kLogOther @"***-***-***O其他-"

@interface ARTWatchSyncFileModel : NSObject

// 获取文件内容的指令
@property (strong, nonatomic)  NSData *listCmd;
// 删除文件内容的指令
@property (strong, nonatomic)  NSData *deleteCmd;

@end

@implementation ARTWatchSyncFileModel

@end

@interface ARTWathDataAnalysis (){
    Byte *_bufferBytes;
    NSInteger _mDataIndex;
    NSInteger _dataLenth;
}

// 记录
@property (strong, nonatomic)  ARTWatchHisModel *hisModel;

// 文件同步数组
@property (strong, nonatomic)  NSMutableArray <ARTWatchSyncFileModel *>*syncFileArray;
// 获取文件内容序号
@property (assign, nonatomic)  NSInteger index;

@end

@implementation ARTWathDataAnalysis

#pragma mark-----------DATA-----------
- (void)analysisData:(NSData *)data{
    if (data.length > 4) {
        Byte *bytes = (Byte *)[data bytes];
//        [self analysisBytes:bytes data:data];
        for (int i = 0; i < data.length; i++) {
            if (_mDataIndex == 0) {
                if (bytes[i] == 0xFE) {
                    _mDataIndex++;
                }else{
                    _mDataIndex = 0;
                }
            }else if (_mDataIndex == 1){
                if (bytes[i] == 0x5A) {
//                    _dataLenth = bytes[i+1]&0xFF;
//                    _bufferBytes = (Byte *)malloc(_dataLenth);
//                    _bufferBytes[0] = bytes[i-1];
//                    _bufferBytes[_mDataIndex++] = bytes[i];
                    if(i+1 > data.length){
                        _mDataIndex =0;
                    }else {
                        _dataLenth = bytes[i+1]&0xff;
                        _bufferBytes = (Byte *)malloc(_dataLenth);
                        _bufferBytes[0] = bytes[i-1];
                        _bufferBytes[_mDataIndex++] = bytes[i];
                    }

                }else{
                    _mDataIndex = 0;
                }
            }else{
//                _bufferBytes[_mDataIndex++] = bytes[i];
                if(_mDataIndex>=4 && _mDataIndex<(_dataLenth-1)){
                    _bufferBytes[_mDataIndex++] = ((bytes[i]&0xf0)|((~bytes[i])&0x0f));
                }else {
                    _bufferBytes[_mDataIndex++] = bytes[i];
                }
                         
                if (_mDataIndex == _dataLenth) {
                    _mDataIndex = 0;
                    // decoder
                    [self analysisBytes:_bufferBytes data:[NSData dataWithBytes:_bufferBytes length:_dataLenth]];
                    if (_bufferBytes != NULL) {
                        free(_bufferBytes);
                        _bufferBytes = NULL;
                    }
                }
            }
        }
    }
}

- (void)analysisBytes:(Byte *)bytes data:(NSData *)data{
    NSString *logMsg = @"<无效数据>";
    NSString *dataString = [ASFHConverter convert_16String_with_16Data:data];
    if (data.length > 4) {
        if (!(bytes[0] == 0xFE && bytes[1] == 0x5A)) {
            // 有效数据必须包含包头
            return;
        }
        if (bytes[3] == 0x10) {
            // ----测量结果命令0x10
            logMsg = @"<0x10>";
            NSLog(@"%@%@:%@",kLogReceive,logMsg,dataString);
            [self analysis_0x10_dataBytes:bytes length:data.length];
        }else if (bytes[3] == 0x11){
            // ----同步时间戳命令0x11
            logMsg = @"<0x11>";
            NSLog(@"%@%@:%@",kLogReceive,logMsg,dataString);
        }else if (bytes[3] == 0x12){
            // ----同步类型0x12
            logMsg = @"<0x12>";
            NSLog(@"%@%@:%@",kLogReceive,logMsg,dataString);
        }else if (bytes[3] == 0x13){
            // ----同步结束0x13
            logMsg = @"<0x13>";
            NSLog(@"%@%@:%@",kLogReceive,logMsg,dataString);
            [self analysis_0x13_dataBytes:bytes length:data.length];
        }else if (bytes[3] == 0x14){
            // ----获取文件列表0x14
            logMsg = @"<0x14>";
            NSLog(@"%@%@:%@",kLogReceive,logMsg,dataString);
            [self analysis_0x14_dataBytes:bytes length:data.length];
        }else if (bytes[3] == 0x15){
            // ----获取指定文件内容命令0x15
            logMsg = @"<0x15>";
            NSLog(@"%@%@:%@",kLogReceive,logMsg,dataString);
            [self analysis_0x15_dataBytes:bytes length:data.length];
        }else if (bytes[3] == 0x17){
            // ----删除指定文件命令0x17
            logMsg = @"<0x17>";
            NSLog(@"%@%@:%@",kLogReceive,logMsg,dataString);
        }else if (bytes[3] == 0x05){
            // ----数据异常
            logMsg = @"<0x05>";
            NSLog(@"%@%@:%@",kLogReceive,logMsg,dataString);
            [QMUITips hideAllTips];
            [QMUITips showWithText:FYLocalizedString(@"sleep_watch_data_exception", @"")];
            [self syncAllComplete];
        }else if (bytes[3] == 0x1B){
            // ----用户设置参数
            if(data.length <= 6) return;
            logMsg = @"<0x1B>";
            NSLog(@"%@%@:%@",kLogReceive,logMsg,dataString);
            NSLog(@"===收到打开usb应答:%@",data);
            if(bytes[4]==3){
                if(bytes[5]==3){
                    [QMUITips showWithText:@"打开成功"];
                }else {
                    [QMUITips showWithText:@"打开失败"];
                }
                return;
            }
            if (data.length > 13) {
                ARTSingleShare.currentSettingData = data;
            }
            if (self.call_0x1B_back) {
                self.call_0x1B_back(data);
            }
        }else if (bytes[3] == 0x1C){
            // ----获取设备总条数
            logMsg = @"<0x1C>";
            NSLog(@"%@%@:%@",kLogReceive,logMsg,dataString);
            if (self.call_0x1C_back) {
                self.call_0x1C_back(data);
            }
        }else if (bytes[3] == 0x1D) {
            // 安全
            NSLog(@"===收到安全应答:%@",data);
            if(bytes[2]==6){
//                sendSync_Time();
//                sendFileTotal();
                if (self.call_0x1D_back) {
                    self.call_0x1D_back(data,YES);
                }
            }else{
                if (self.call_0x1D_back) {
                    self.call_0x1D_back(data,NO);
                }
            }
        }
    }else{
        NSLog(@"%@%@:%@",kLogReceive,logMsg,dataString);
    }
}

// ----测量结果命令0x10
- (void)analysis_0x10_dataBytes:(Byte *)bytes length:(NSInteger)length{
    if (length >= 18) {
        ARTWathDataModel *dataModel = [[ARTWathDataModel alloc]init];
        // 脉率数据的高字节bytes[4] 脉率数据的低字节bytes[5]
        int pr = (bytes[4]&0xff<<8) | (bytes[5]&0xff);//(bytes[5] | (bytes[4]<<8));
        dataModel.pr = pr > 250 ? 0 : pr;//pr >= 511 ? 0 : pr;
        // 血氧值
//        int spo2 = bytes[6];
        dataModel.spo2 = (bytes[6] > 100 ? 0 : bytes[6]&0xff);//spo2 >= 127 ? 0 : spo2;
        // 灌注指数的高字节bytes[7] 灌注指数的低字节bytes[8]
        dataModel.pi = ((bytes[7]&0xff)<<8 | (bytes[8]&0xff))/1000.0f;//(bytes[8] | (bytes[7]<<8))/1000.0;
        // 电量
        dataModel.battery = bytes[9];
        // 时间
        dataModel.timeInterval = ((bytes[12]&0xff)<<8 | (bytes[13]&0xff));//(bytes[13] | (bytes[12]<<8));
        // 类型
        dataModel.type = bytes[14];
        // 预警值
        dataModel.lowSpo = bytes[15];
        dataModel.highPr = bytes[16]&0xff;
        dataModel.lowPr = bytes[17]&0xff;
        // 固件版本
        dataModel.nowVersion = (bytes[10]&0xff<<8) | (bytes[11]&0xff);
        J_UserDefault_SetObjectForKey(@(dataModel.nowVersion), ART_Storage_WatchVersion);
        if (self.call_0x10_back) {
            self.call_0x10_back(dataModel);
        }
        NSLog(@"%@",[dataModel description]);
    }
}

// ----测量结束0x14
- (void)analysis_0x13_dataBytes:(Byte *)bytes length:(NSInteger)length{
    if (length > 5) {
        BOOL stop = !bytes[4];
        if (self.call_0x13_back) {
            self.call_0x13_back(stop);
        }
    }
}

// ----获取文件列表0x14
- (void)analysis_0x14_dataBytes:(Byte *)bytes length:(NSInteger)length{
    if (length >= 7) {
        Byte byte[] = {0xFE,0x5A,0x07,0x15,bytes[4],bytes[5],0x00};
        if (self.isSyncFile) {
            // 同步文件
            if (bytes[4] == 0xFF && bytes[5] == 0xFF) {
                NSLog(@"%@文件列表传输完成count:%@",kLogOther,@(self.syncFileArray.count));
                [self getAllContent];
            }else if (bytes[4] == 0xFE && bytes[5] == 0xFE){
                NSLog(@"%@当前状态下不可同步数据",kLogOther);
                [QMUITips hideAllTips];
                [QMUITips showWithText:@"当前状态下不可同步数据"];
            }else{
                ARTWatchSyncFileModel *file = [[ARTWatchSyncFileModel alloc]init];
                file.listCmd = [NSData dataWithBytes:byte length:7];
                Byte delete[] = {0xFE,0x5A,0x06,0x17,bytes[4],bytes[5]};
                file.deleteCmd = [NSData dataWithBytes:delete length:6];
                [self.syncFileArray addObject:file];
            }
        }else{
            NSLog(@"获取监测文件列表");
            if (self.call_0x14_back) {
                self.call_0x14_back([NSData dataWithBytes:byte length:7]);
            }
        }
    }
}

// 获取文件内容
- (void)getAllContent{
    if (self.syncFileArray.count == 0) {
        if (self.call_syncComplete_back) {
            self.call_syncComplete_back(@[]);
        }
        return;
    }
    ARTWatchSyncFileModel *file = self.syncFileArray[_index];
    if (file.listCmd) {
        // 获取文件内容
        NSLog(@"%@<0x14><index=%@>:%@",kLogSend,file.listCmd,@(_index));
        [ARTSingleShare.currentPeripheral writeValue:file.listCmd forCharacteristic:ARTSingleShare.writeCharacteristic type:CBCharacteristicWriteWithResponse];
    }
}

// ----获取指定文件内容命令0x15
- (void)analysis_0x15_dataBytes:(Byte *)bytes length:(NSInteger)length{
    if (bytes[4] == 0x00) {
        // 文件头
    }else if (bytes[4] == 0x01){
        // 数据包
        int count = 0;
        ARTWathDataModel *item;
        for (int i = 7; i < length - 1; i++) {
            if(i >= 80 && i <= 87){
                continue;
            }
            if (count == 0) {
                item = [[ARTWathDataModel alloc]init];
            }
            if (i % 2 != 0) {
                int spo2 = bytes[i]&0x7F;
//                spo2 = spo2 >= 127 ? 0 : spo2;
                spo2 = spo2 > 100 ? 0 : spo2;
                if (spo2 > 0) {
                    if (spo2 < 85){
                        self.hisModel.spo2_85++;
                    }else if (spo2 < 90){
                        self.hisModel.spo2_90++;
                    }else if (spo2 < 95){
                        self.hisModel.spo2_95++;
                    }else if (spo2 >= 95){
                        self.hisModel.spo2_max95++;
                    }
                }
                item.spo2 = spo2;
                NSLog(@"%@<spo:%@>:%@",kLogOther,@(item.spo2),[ASFHConverter convert_16String_with_16Data:[NSData dataWithBytes:bytes length:length]]);
            }else{
                int pr = ((((bytes[i-1]&0xFF)>>7)<<8)) | (bytes[i]&0xFF);
//                pr = pr >= 511 ? 0 : pr;
                pr = pr > 250 ? 0 : pr;
                if (pr > 0) {
                    if (pr > 100) {
                        self.hisModel.pr_high++;
                        self.hisModel.pr_100++;
                    }else if (pr < 60){
                        self.hisModel.pr_low++;
                        self.hisModel.pr_60++;
                    }else{
                        self.hisModel.pr_normal++;
                    }
                }
                item.pr = pr;
            }
            count++;
            if (count == 2) {
                [self.hisModel.dataList addObject:item];
                count = 0;
            }
        }
    }else if (bytes[4] == 0x02){
        // 报告
        if (length > 76) {
            CGFloat odi = (bytes[20]<<8 | bytes[19]);
            self.hisModel.odi = @(odi*1.0/10).floatValue;
            CGFloat AHI = (bytes[22]<<8 | bytes[21]);
            self.hisModel.AHI = @(AHI*1.0/10).floatValue;
            self.hisModel.prMax = (bytes[24]&0xFF)<<8 | (bytes[23]&0xFF);
            self.hisModel.prMin = (bytes[26]&0xFF)<<8 | (bytes[25]&0xFF);
            self.hisModel.prAvg = (bytes[28]&0xFF)<<8 | (bytes[27]&0xFF);
            self.hisModel.spo2Max = bytes[44]&0xFF;
            self.hisModel.spo2Min = bytes[42]&0xFF;
            self.hisModel.spo2Avg = bytes[43]&0xFF;
            
            self.hisModel.time_awake = bytes[34]<<8 | (bytes[33]&0XFF);
            self.hisModel.time_light_sleep = bytes[36]<<8 | (bytes[35]&0XFF);
            self.hisModel.time_deep_sleep = bytes[38]<<8 | (bytes[37]&0XFF);
            self.hisModel.time_start = ((bytes[14]&0XFF)<<24 | (bytes[13]&0XFF)<<16 | (bytes[12]&0XFF)<<8 | (bytes[11]&0XFF)) - [ARTWathDataAnalysis offsetOfDate:[NSDate date]];
            self.hisModel.time_end = ((bytes[18]&0XFF)<<24 | (bytes[17]&0XFF)<<16 | (bytes[16]&0XFF)<<8 | (bytes[15]&0XFF)) - [ARTWathDataAnalysis offsetOfDate:[NSDate date]];
            self.hisModel.type = bytes[41];
            NSLog(@"%@测量类型:%@",kLogOther,@(self.hisModel.type));
            self.hisModel.testResult = bytes[45]&0xff;
            self.hisModel.oxygenLowTotal = (bytes[50]&0XFF)<<8 | (bytes[49]&0XFF);
            self.hisModel.oxygenTimeLow = (bytes[52]&0XFF)<<8 | (bytes[51]&0XFF);
            
            // 睡眠分期
            for(int i = 55; i < length - 1; i++){
                if(bytes[i] != 0){
                    int value = ((int) bytes[i]-1);
                    if (value < 3) {
                        [self.hisModel.sleepStages addObject:@(value)];
                    }
                }
            }
        }else{
            // 睡眠分期
            for(int i = 7; i < length - 1; i++){
                if(bytes[i] != 0 ){
                    int value = ((int) bytes[i]-1);
                    if (value < 3) {
                        [self.hisModel.sleepStages addObject:@(value)];
                    }
                }
            }
        }
    }else if (bytes[4] == 0xFF){
        if (bytes[5] == 0xFF) {
            // 传输完成
            if (_isSyncFile) {
                ARTWatchHisModel *hisModel = [self.hisModel modelCopy];
                // 实时保存数据
                [hisModel save];
                // 删除文件
                ARTWatchSyncFileModel *file = self.syncFileArray[_index];
                NSLog(@"%@<0x17><index=%@>:%@",kLogSend,@(_index),file.deleteCmd);
                [ARTSingleShare.currentPeripheral writeValue:file.deleteCmd forCharacteristic:ARTSingleShare.writeCharacteristic type:CBCharacteristicWriteWithResponse];
                
                _hisModel = nil;
                _index++;
                if (_index < self.syncFileArray.count) {
                    NSLog(@"%@同步新一轮数据<index=%@,all=%@>",kLogOther,@(_index),@(self.syncFileArray.count));
                    [self getAllContent];
                }else{
                    NSLog(@"%@所有文件同步完成",kLogOther);
                    [self syncAllComplete];
                }
            }else{
                NSLog(@"%@测量后文件同步完成",kLogOther);
                if (self.call_0x15_back) {
                    self.call_0x15_back(self.hisModel);
                }
            }
        }
    }
}

// 同步完成回调
- (void)syncAllComplete{
    if (self.call_syncComplete_back) {
        self.call_syncComplete_back(self.syncFileArray);
    }
    [self clearData];
}

// 同步所有文件列表
- (BOOL)syncAllFileList{
//    if (!_canSync) {
//        [QMUITips showWithText:@"当前状态下不可同步数据"];
//        return NO;
//    }
    _bufferBytes = NULL;
    Byte byte[] = {0xFE,0x5A,0x05,0x14,0x03};
    NSData *data = [NSData dataWithBytes:byte length:5];
    [ARTSingleShare.currentPeripheral writeValue:data forCharacteristic:ARTSingleShare.writeCharacteristic type:CBCharacteristicWriteWithResponse];
    return YES;
}

// 清除缓存数据
- (void)clearData{
    [_syncFileArray removeAllObjects];
    _syncFileArray = nil;
    _index = 0;
    _hisModel = nil;
    _isSyncFile = NO;
    if (_bufferBytes != NULL) {
        free(_bufferBytes);
        _bufferBytes = NULL;
    }
    _mDataIndex = 0;
    _dataLenth = 0;
}

#pragma mark-----------CMD-----------
+ (NSTimeInterval)offsetOfDate:(NSDate *)date{
    //设置源日期时区
    NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];//或GMT
    //设置转换后的目标日期时区
    NSTimeZone* destinationTimeZone = [NSTimeZone localTimeZone];
    //得到源日期与世界标准时间的偏移量
    NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:date];
    //目标日期与本地时区的偏移量
    NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:date];
    //得到时间偏移量的差值
    NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;
    return interval;
}

// 同步时间戳
+ (NSData *)syncTimestamp{
    NSDate *date = [NSDate date];
    
    //得到时间偏移量的差值
    NSTimeInterval interval = [self offsetOfDate:date];
    //转为现在时间
    NSDate* destinationDateNow = [[NSDate alloc] initWithTimeInterval:interval sinceDate:date];
    long time = [destinationDateNow timeIntervalSince1970];
    
    Byte byteData[4] = {};
    byteData[0] = time>>24&0xFF;
    byteData[1] = time>>16&0xFF;
    byteData[2] = time>>8&0xFF;
    byteData[3] = time&0xFF;
    
    Byte byte[] = {0xFE,0x5A,0x08,0x11,byteData[0],byteData[1],byteData[2],byteData[3]};
    NSData *data = [NSData dataWithBytes:byte length:8];
    NSLog(@"%@同步时间戳time:%@,data:%@",kLogOther,@(time),data);
    
    return data;
}

// 同步类型
+ (NSData *)syncMeasuringType:(ARTWatchMonitorType)type{
    Byte byteData[1] = {};
    if (type == ARTWatchMonitorTypeDaily) {
        byteData[0] = 0x01;
    }else if (type == ARTWatchMonitorTypeSleep){
        byteData[0] = 0x02;
    }
    
    Byte byte[] = {0xFE,0x5A,0x05,0x12,byteData[0]};
    NSData *data = [NSData dataWithBytes:byte length:5];
    NSLog(@"%@同步类型data:%@",kLogOther,data);
    return data;
}

// 同步结束
+ (NSData *)syncStop{
    Byte byte[] = {0xFE,0x5A,0x05,0x13,0x01};
    NSData *data = [NSData dataWithBytes:byte length:5];
    NSLog(@"%@同步结束data:%@",kLogOther,data);
    return data;
}

// 获取设备总条数
+ (NSData *)getDeviceHisAllCount{
    Byte byte[] = {0xFE,0x5A,0x06,0x1C,0x01,0x00};
    NSData *data = [NSData dataWithBytes:byte length:6];
    NSLog(@"%@获取设备总条数data:%@",kLogOther,data);
    return data;
}

// 同步删除
//+ (NSData *)synDelete{
//    Byte byte[] = {0xFE,0x5A,0x05,0x13,0x01};
//    NSData *data = [NSData dataWithBytes:byte length:5];
//    {(byte) 0xFE,0x5A,0x07,0x17,0,0,0}
//}

- (ARTWatchHisModel *)hisModel{
    if (!_hisModel) {
        _hisModel = [[ARTWatchHisModel alloc]init];
        _hisModel.dataList = [NSMutableArray array];
        _hisModel.sleepStages = [NSMutableArray array];
    }
    return _hisModel;
}

- (NSMutableArray<ARTWatchSyncFileModel *> *)syncFileArray{
    if (!_syncFileArray) {
        _syncFileArray = [NSMutableArray array];
    }
    return _syncFileArray;
}

/**
 //同步时间
 byte sync_Time []={(byte) 0xFE,0x5A,0x0A,0x11,0,0,0,0,0,0};
 //日常测量
 byte sync_Daily []={(byte) 0xFE,0x5A,0x06,0x12,0,0};
 //结束测量
 byte sync_end []={(byte) 0xFE,0x5A,0x06,0x13,1,0};
 //获取文件列表
 byte get_Filelist []={(byte) 0xFE,0x5A,0x06,0x14,3,0};
 //获取指定文件内容命令
 byte get_appointFile []={(byte) 0xFE,0x5A,0x07,0x15,0,0,0};
 //获取指定数据帧内容命令
 byte get_FrameFile []={(byte) 0xFE,0x5A,0x07,0x16,0,0,0};
 //删除指定内容命令
 byte delete_appointFile []={(byte) 0xFE,0x5A,0x07,0x17,0,0,0};
 
 0x14应答包
 <fe5a2e14 00000000 0180617b 1ee2536c 6565705f 30303131 30323832 30323132 32303631 352e626c 65000000 0000>
 
 0x15应答包
 <fe5a5015 00000055 4e303030 30303020 20202020 20202020 20202020 20202020 20202020 20202020 20202020 20202020 20202020 20202020 20202020 20202020 20202020 20202020 20202020 20202028
 fe5a2015 00000120 20202020 20202032 382e3130 2e323132 322e3433 2e313149
 fe5a5015 01000264 48644864 48644864 48644863 47634762 47624762 47624762 47624762 47624762 47624762 47624762 47624762 47624762 47624762 47624762 49624962 49624962 49624962 49624950
 fe5a5015 01000362 49624961 48614861 49614961 49614961 49614961 49614961 4a614a61 4a614a61 4a614a62 4a624a62 4a624a62 4b624b62 4c624c62 4e624e62 4e624e62 4e624e62 50625062 4e624ead
 fe5a0a15 01000462 4fd5fe5a 50150200 057f277b 6193277b 61db277b 61000000 00500047 00490000 00000000 00000000 00000001 61616400 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0069
 fe5a 48150200 06000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0065
 fe5a 0715ffff 1a>
 */

#pragma mark - 安全
- (void)sendSafe:(dispatch_block_t)complete{
    
}

@end
